<!-- 表单 》 头像 -->

<template>
  <el-form-item v-bind="formItem">
    <!-- 标签 -->
    <template v-if="hasLabelSlot" #label>
      <slot name="label" :label="formItem.label">{{ formItem.label }}</slot>
    </template>

    <div :class="divClass" :style="divStyle">
      <!-- 删除按钮 -->
      <div v-if="model" :class="delClass" @click="toDel">
        <img v-if="ICON.delImg" :src="ICON.delImg" />
        <i v-else :class="ICON.delIcon" />
      </div>

      <!-- 预览图 -->
      <el-image v-if="model" v-bind="imgProps" />

      <!-- 上传组件 -->
      <el-upload v-show="!model" v-bind="uploadProps">
        <div>
          <img v-if="ICON.upImg" :src="ICON.upImg" />
          <i v-else :class="ICON.upIcon" />

          <div v-if="tipText">{{ tipText }}</div>
        </div>
      </el-upload>
    </div>
  </el-form-item>
</template>

<script>
// ============================== 导入依赖 ============================== //

import CORE from '@/CORE'
import mixForm from '../mixForm'
import FormImage from '../FormImage'

const name = 'FormPhoto'

// ============================== 导出组件 ============================== //

export default {
  /**
   * 名称定义 (实际使用名称)
   */
  name,

  /**
   * 混入列表 (配置选项合并)
   */
  mixins: [mixForm],

  /**
   * 属性注册 (抽取以便查阅)
   */
  props: CORE.WEB[name],

  /**
   * 状态数据 (函数返回对象)
   */
  data() {
    return {
      drag: false,
      model: '', // 内部绑定值
      EMPTY: '', // 空值常量
    }
  },

  /**
   * 计算属性 (慎用箭头函数)
   */
  computed: {
    /**
     * 上传类型
     */
    uploadType: FormImage.computed.uploadType,

    /**
     * 业务标识
     */
    businessTag: FormImage.computed.businessTag,

    /**
     * 图标对象
     */
    ICON: FormImage.computed.ICON,

    /**
     * 填充属性
     */
    fit: FormImage.computed.fit,

    /**
     * 容器样式类
     */
    divClass() {
      const { className, square, height, rows, isDisabled } = this
      const disabledStr = isDisabled ? ` ${className}-disabled` : ''

      if (square) return `${className}${disabledStr} CoreWeb-WebForm-square`
      if (height) return `${className}${disabledStr}`

      // row1 到 row10
      let num = rows
      const array9 = Array(10).fill()
      for (const i of array9.map((_, i) => 10 - i)) {
        if (this[`row${i}`]) num = i
      }
      return `${className}${disabledStr} row${num}`
    },

    /**
     * 容器样式对象
     */
    divStyle() {
      const { getSize, square, squareSize, height } = this
      return { width: square ? getSize(squareSize) : null, height: getSize(square ? squareSize : height) }
    },

    /**
     * 删除的样式类
     */
    delClass() {
      const { className, commonProps, autoDel } = this
      if (commonProps.disabled) return `${className}-del ${className}-del-hide`
      if (autoDel) return `${className}-del ${className}-del-auto`
      return `${className}-del`
    },

    /**
     * 图片属性
     */
    imgProps() {
      const { model, fit, pathTrans, noTrans } = this
      const src = noTrans ? model : pathTrans(model)
      return { src, fit, previewSrcList: [src] }
    },

    /**
     * 上传属性
     */
    uploadProps() {
      const { className, beforeUpload } = this
      const accept = this.jpg ? 'image/jpeg' : this.png ? 'image/png' : this.svg ? 'image/svg+xml' : this.accept
      return {
        ...this.elProps,
        class: `${className}-upload`,
        action: '',
        drag: true,
        showFileList: false,
        accept,
        beforeUpload,
        disabled: this.isDisabled,
      }
    },

    /**
     * 提示文字
     */
    tipText() {
      const { noText, text, label } = this
      return noText ? '' : text || `上传${label}`
    },
  },

  /**
   * 本地方法 (轻量重要在前)
   */
  methods: {
    /**
     * 检查文件
     */
    checkFile: FormImage.methods.checkFile,

    /**
     * 获取文件夹
     */
    getFolder: FormImage.methods.getFolder,

    /**
     * 上传之前
     */
    beforeUpload(file) {
      if (!this.checkFile(file)) return false

      const folder = this.getFolder()
      const tag = this.businessTag
      const type = this.uploadType

      const success = (url) => {
        this.model = url || this.EMPTY
        this.emitChange()
        this.$emit('uploaded', file.name)
      }
      const error = (err) => CORE.MSG.error(err.message || '上传失败')

      if (this.upload) this.upload(file, folder, tag, type).then(success).catch(error)
      else CORE.imageUpload(file, folder, tag).then(success).catch(error)

      return false
    },

    /**
     * 点击删除
     */
    toDel() {
      const { init, EMPTY, emitChange } = this
      this.model = init || EMPTY
      emitChange()
    },
  },
}
</script>
